package com.ruoyi.common.orm.handler;

import com.ruoyi.common.core.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.MyBatisSystemException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Mybatis异常处理器
 *
 * @author Lion Li
 */
@Slf4j
@RestControllerAdvice
public class MybatisExceptionHandler {

    /**
     * 主键或UNIQUE索引，数据重复异常
     */
    @ExceptionHandler(DuplicateKeyException.class)
    public R<Void> handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        log.error("请求地址'{}',数据库中已存在记录'{}'", requestURI, e.getMessage());

        // 默认的错误信息
        String duplicateKeyMessage = "数据库中已存在该记录，请联系管理员确认";

        // 判断当前接口是否为发票插入接口
        if (requestURI.contains("/invoice/invoice")) {
            // 如果是发票插入接口，进行特定处理
            duplicateKeyMessage = handleInvoiceDuplicateKey(e);
        }

        // 返回处理后的响应
        return R.fail(duplicateKeyMessage);
    }

    /**
     * 处理发票插入的 DuplicateKeyException
     */
    private String handleInvoiceDuplicateKey(DuplicateKeyException e) {
        String errorMessage = e.getMessage();
        String duplicateKeyMessage = "数据库中已存在该记录，请联系管理员确认"; // 默认错误信息

        // 正则表达式提取重复的字段和值
        Pattern pattern = Pattern.compile("Key \\((.*?)\\)=\\((.*?)\\)");
        Matcher matcher = pattern.matcher(errorMessage);

        if (matcher.find()) {
            String fieldName = matcher.group(1);  // 重复字段名，如 invoice_number
            String fieldValue = matcher.group(2); // 重复的值，如 01060324

            // 构建具体的错误信息
            if ("invoice_number".equals(fieldName)) {
                duplicateKeyMessage = String.format("发票号码 %s 已存在", fieldValue);
            } else {
                duplicateKeyMessage = String.format("%s %s 已存在", fieldName, fieldValue);
            }
        }

        return duplicateKeyMessage;
    }

    /**
     * Mybatis系统异常 通用处理
     */
    @ExceptionHandler(MyBatisSystemException.class)
    public R<Void> handleCannotFindDataSourceException(MyBatisSystemException e, HttpServletRequest request) {
        String requestURI = request.getRequestURI();
        String message = e.getMessage();
        if (StringUtils.contains("CannotFindDataSourceException", message)) {
            log.error("请求地址'{}', 未找到数据源", requestURI);
            return R.fail("未找到数据源，请联系管理员确认");
        }
        log.error("请求地址'{}', Mybatis系统异常", requestURI, e);
        return R.fail(message);
    }

}
